//
//  KBEmoticon.swift
//  05-表情键盘
//
//  Created by kimbo on 15/12/28.
//  Copyright © 2015年 kimbo. All rights reserved.
//

import UIKit

// MARK: - 表情包模型
class KBEmoticonPackage: NSObject {
    // MARK: - 属性
    /// id表情包的文件夹名称
    var id: String
    
    /// 表情包的名称
    var group_name_cn: String?
    
    /// 所有的表情模型
    var emoticons: [KBEmoticon] = [KBEmoticon]()
    
    /// 根目录
    static let bundlePath = NSBundle.mainBundle().pathForResource("Emoticons.bundle", ofType: nil)!
    
    // 对象的打印
    override var description: String {
        return "\n\t表情包模型: id:\(id), group_name_cn: \(group_name_cn), emoticons: \(emoticons))"
    }
    
    /// 加载所有表情包(只加载一次)
    static let packages = KBEmoticonPackage.loadPackages()
    
    /// 表情包构造函数
    init(id: String) {
        self.id = id
        super.init()
    }
    
    /// 加载所有表情包模型
    class func loadPackages() -> [KBEmoticonPackage]? {
        //加载到emoticons.plist,可以知道有每个表情包的文件夹名称
        let plistPath = (bundlePath as NSString).stringByAppendingPathComponent("emoticons.plist")
        
        let emoticonDict = NSDictionary(contentsOfFile: plistPath)!
        
        guard let arr = emoticonDict["packages"] as? [[String: AnyObject]] else {
            return nil //如果没有返回nil
        }
        
        // 如果有，遍历数组并创建表情包模型数组返回
        var packages = [KBEmoticonPackage]()
        
        //1 创建最近表情包
        let recentPackage = KBEmoticonPackage(id: "")
        
        recentPackage.group_name_cn = "最近"
        
        //2 加入数组
        packages.append(recentPackage)
        
        //3 最近表情包添加空白表情和删除按钮
        recentPackage.addEmptyEmoticon()
        
        for dict in arr {
            let id = dict["id"] as! String
            
            let package = KBEmoticonPackage(id: id)
            
            // 加载表情包里面的表情模型
            package.loadEmoticon()
            
            packages.append(package)
        }
        // 返回所有表情包模型
        return packages
    }
    
    
    /// 加载所有的表情,加载表情包的名称
    func loadEmoticon() {
        // 加载info.plist全路径 = bundlePath + id + info.plist
        let infoPlistPath = ((KBEmoticonPackage.bundlePath as NSString).stringByAppendingPathComponent(id) as NSString).stringByAppendingPathComponent("info.plist")
        
        let dict = NSDictionary(contentsOfFile: infoPlistPath)!
        // 表情包的名称
        group_name_cn = dict["group_name_cn"] as? String
        
        if let emoticonsArr = dict["emoticons"] as? [[String: AnyObject]] {
            var index = 0
            for dict in emoticonsArr {
                let emoticon = KBEmoticon(id: id, dict: dict)
                
                emoticons.append(emoticon)
                
                index++
                // 如果是第21个表情就添加删除按钮
                if index == 20 {
                    emoticons.append(KBEmoticon(removeEmoticon: true))
                    // 清空
                    index = 0
                }
            }
        }
        
        // 最后判断最后一页是否满一页，不满就添加空白表情和删除按钮
        addEmptyEmoticon()
    }
    
    /// 添加空白表情和删除按钮
    func addEmptyEmoticon() {
        // (最后一页)不满一页的count个表情
        let count = emoticons.count % 21
        
        // count == 0 刚好满一页; count != 0 不满一页
        // 一开始最近表情包没有表情，需要emoticons.count == 0这个条件来进入代码
        if count > 0 || emoticons.count == 0 {
            // count == 1,需要添加19(20 - 1)(1..<20)个空白表情和一个删除按钮
            // count == 2,需要添加18(20 - 2)(2..<20)个空白表情和一个删除按钮
            for _ in count..<20 {
                //添加空白表情
                emoticons.append(KBEmoticon(removeEmoticon: false))
            }
            
            // 最后一个添加删除按钮
            emoticons.append(KBEmoticon(removeEmoticon: true))
        }
    }
    
    /// 添加表情模型到最近表情包
    class func addFavorateEmoticon(emoticon: KBEmoticon) {
        // 删除按钮不需要添加到表情包
        if emoticon.removeEmoticon {
            return
        }
        
        // 空白按钮不需要排序,不能通过emoticon.removeEmoticon == false来判断是空表情
        if emoticon.pngString == nil && emoticon.emoji == nil {
            return
        }
        
        emoticon.times++
        
        // 获取最近表情包所有表情模型
        var recentEmoticons = packages![0].emoticons
        
        // 将删除按钮移除，不参加排序
        let removeEmoticon = recentEmoticons.removeLast()
        
        // 判断最近包是否包含这个表情
        let contains = recentEmoticons.contains(emoticon)
        
        // 没有包含这个表情才加入最近表情包中
        if !contains {
            recentEmoticons.append(emoticon)
        }
        
        // 数组排序,需要重新赋值
        recentEmoticons = recentEmoticons.sort { (e1, e2) -> Bool in
            return e1.times > e2.times //用次数多的排在前面
        }
        
        // 如果上面有添加表情，就要删除一个以保持最近表情包21个表情
        if !contains {
            recentEmoticons.removeLast()
        }
        
        // 再把删除按钮添加回去
        recentEmoticons.append(removeEmoticon)
        
        // 千万要记得重新赋值.recentEmoticons 改变 packages![0].emoticons不会跟着改
        packages![0].emoticons = recentEmoticons
    }
}


// MARK: - 表情模型
class KBEmoticon: NSObject {
    /// id 表情包文件夹名称
    var id: String?
    
    /// 表情名称,用于网络传输
    var chs: String?
    
    /// 表情图片名称(客户端显示)
    var png: String? {
        didSet {
            pngString = KBEmoticonPackage.bundlePath + "/\(id!)/\(png!)"
        }
    }
    
    /// 表情图片路径
    var pngString: String?
    
    /// code用于显示emoji表情
    var code: String? {
        didSet {
            // kvc设置code之后,将code转成emoji表情
            // 创建扫描器
            let scanner = NSScanner(string: code!)
            
            // 扫描
            var result: UInt32 = 0
            scanner.scanHexInt(&result)
            let scalar = UnicodeScalar(result)
            
            let character = Character(scalar)
            emoji = String(character)
        }
    }
    
    /// emoji表情字符
    var emoji: String?
    
    /// 表情模型的使用次数，次数越多显示越前
    var times = 0
    
    /// 删除按钮，true表示删除按钮，false表示空白按钮
    var removeEmoticon = false
    
    /// 删除或空白按钮表情的构造方法
    init(removeEmoticon: Bool) {
        self.removeEmoticon = removeEmoticon
        super.init()
    }
    
    init(id: String?, dict: [String: AnyObject]) {
        super.init()
        
        self.id = id
        
        setValuesForKeysWithDictionary(dict)
    }
    
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
    
    /// 打印表情模型
    override var description: String {
        return "\n\t\t表情模型:chs: \(chs), png: \(png), code: \(code)"
    }
}


